package eu.catengine.common.manager;

import java.util.HashMap;

import eu.catengine.common.iface.IDisposable;
import eu.catengine.common.iface.IManager;
import eu.catengine.graphic.Texture;
import eu.catengine.graphic.TextureAnimation;
import eu.catengine.graphic.TextureRegion;
import eu.catengine.primitive.Size;

/**
 * Manager odpowiedzialny za przechowywanie danych animacji.
 * 
 * @author mbienkowski
 */
public class AnimationManager implements IDisposable, IManager<AnimationManager, TextureAnimation>
{
    private static volatile AnimationManager mInstance;
    private HashMap<String, TextureAnimation> mAnimationHashMap;

    private AnimationManager()
    {
	mAnimationHashMap = new HashMap<String, TextureAnimation>();
    }

    /**
     * Zwraca instanację managera.
     */
    public static AnimationManager getInstance()
    {
	if (mInstance == null)
	{
	    mInstance = new AnimationManager();
	}
	return mInstance;
    }

    /**
     * Ładuje animację do managera.<br>
     * Metoda wykorzystywana w przypadku, gdy poszczególne klatki animacji
     * znajduja się w jednej linii.
     * 
     * @param animationName
     *            <code>String</code> Nazwa animacji.
     * @param texture
     *            <code>Texture</code> Tekstura animacji.
     * @param frameSize
     *            <code>Size</code> Rozmiar pojedynczej klatki animacji.
     * @param frames
     *            <code>int</code> Ilość klatek animacji.
     * @param duration
     *            <code>int</code> Czas trwania animacji.
     * @return <code>TextureAnimation</code> zwraca stworzony obiekt.
     */
    public TextureAnimation loadAnimation(String animationName, Texture texture, Size frameSize, int frames, int duration)
    {
	TextureRegion[] regions = texture.getTextureRegions(frameSize, frames);
	TextureAnimation animation = new TextureAnimation(animationName, texture, regions, duration, frames);

	mAnimationHashMap.put(animationName, animation);

	return animation;
    }

    /**
     * Ładuje animację do managera.<br>
     * Metoda wykorzystywana w przypadku, gdy poszczególne klatki animacji nie
     * znajduja się w jednej linii, lecz w kwadracie.
     * 
     * @param animationName
     *            <code>String</code> Nazwa animacji.
     * @param texture
     *            <code>Texture</code> Tekstura animacji.
     * @param frameSize
     *            <code>Size</code> Rozmiar pojedynczej klatki animacji.
     * @param frames
     *            <code>int</code> Ilość klatek animacji.
     * @param framesInLine
     *            <code>int</code> Ilość klatek w jednej linii.
     * @param duration
     *            <code>int</code> Czas trwania animacji.
     * @return <code>TextureAnimation</code> zwraca stworzony obiekt.
     */
    public TextureAnimation loadAnimation(String animationName, Texture texture, Size frameSize, int frames, int framesInLine, int duration)
    {
	TextureRegion[] regions = texture.getTextureRegions(frameSize, frames, framesInLine);
	TextureAnimation animation = new TextureAnimation(animationName, texture, regions, duration, frames);

	mAnimationHashMap.put(animationName, animation);

	return animation;
    }

    @Override
    public TextureAnimation get(String name)
    {
	return mAnimationHashMap.get(name);
    }

    @Override
    public void remove(String name)
    {
	mAnimationHashMap.remove(name);
    }

    @Override
    public void remove(TextureAnimation object)
    {
	mAnimationHashMap.remove(object);
    }

    @Override
    public void dispose()
    {
	for (TextureAnimation tmp : mAnimationHashMap.values())
	{
	    tmp.dispose();
	}
	mAnimationHashMap.clear();

	mAnimationHashMap = null;
	mInstance = null;
    }

}
